package com.StarStudio.Service.Impl;


import com.StarStudio.DAO.PanicBuyingOrdersDAO;
import com.StarStudio.Service.*;
import com.ruoyi.common.core.Entity.*;
import com.ruoyi.common.core.utils.HttpRequestUtils;
import com.ruoyi.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

@Service
public class PanicBuyingOrdersServiceImpl implements PanicBuyingOrdersService {

    @Autowired
    PanicBuyingOrdersDAO panicBuyingOrdersDAO;

    @Autowired
    PanicBuyingGoodsService panicBuyingGoodsService;

    @Autowired
    PanicBuyingCouponsService panicBuyingCouponsService;

    @Autowired
    RedisService redisService;

    @Autowired
    OrdersService ordersService;

    @Autowired
    GoodsStockService goodsStockService;

    @Autowired
    CouponsStockService couponsStockService;

    @Autowired
    ExchangeService exchangeService;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    GoodsService goodsService;

    @Autowired
    BeansActionService beansActionService;

    @Autowired
    CouponsService couponsService;

    @Override
    public List<PanicBuyingOrders> findPanicBuyingOrdersList(PanicBuyingOrders panicBuyingOrders) {
        return panicBuyingOrdersDAO.findPanicBuyingOrdersList(panicBuyingOrders);
    }

    @Override
    public long findTotalRecord() {
        return panicBuyingOrdersDAO.findTotalRecord();
    }

    /**
     * 真正生成订单
     * @param orders 订单对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void NewPanicBuyingOrders(Orders orders) {
        if (orders.getGoods_id() > 0){ /* 实体商品 */
            //拿到抢购商品对象
            PanicBuyingGoods panicBuyingGoods = panicBuyingGoodsService.findByGoods_id(orders.getGoods_id());
            List<GoodsStock> unsoldItems = goodsStockService.findUnsoldItems(orders.getGoods_id(), false);
            if (panicBuyingGoods.getPanic_buying_goods_stock() >= 1 && unsoldItems.size() > 0){ //解决库存超卖
                panicBuyingGoods.setPanic_buying_goods_stock(panicBuyingGoods.getPanic_buying_goods_stock() - 1);
                int i = (int)panicBuyingGoodsService.updatePanicBuyingGoods(panicBuyingGoods).getObject();
                if (i == 0){  //用户执行减库存的操作失败了，但是依然会去执行下订单的操作，这样就产生了生成的订单数大于卖出的商品数的问题
                    return; //解决办法：判断 update语句是否执行成功，如果未执行成功，直接返回
                    // 注意：mybatis的update语句默认返回匹配的行数，而不是影响的行数，故在jdbc的 URL上加 &useAffectedRows=true
                }
                //往订单表写入数据
                orders.setOrder_status(MessageConstant.ORDER_ALREADY_PAID);//更新订单状态
                orders.setOrder_time(new Timestamp(new Date().getTime())); //添加下单时间
                ordersService.OrderInsert(orders);
                //往 GoodsStock中更新数据
                GoodsStock goodsStock = unsoldItems.get(0);
                goodsStock.setHave_been_sold(true);
                goodsStock.setSold_order_id(orders.getOrder_id());
                goodsStock.setSold_time(new Timestamp(new Date().getTime()));
                goodsStockService.updateGoodsStock(goodsStock);
                // 往 Exchange中更新数据
                Exchange exchange = new Exchange();
                exchange.setExchange_status(MessageConstant.EXCHANGE_STATUS_USED);
                exchange.setOrder_id(orders.getOrder_id());
                exchange.setExchange_user_id(orders.getOrder_user_id());
                exchange.setGoods_item_id(goodsStock.getItem_id());
                exchange.setUse_time(new Timestamp(new Date().getTime()));
                exchangeService.addExchange(exchange);
            }else {
                //如果没有库存 在 Redis中进行标记（有key即可）
                redisService.setCacheObject("isPBGoodsStockEmpty" + orders.getGoods_id(),0);
                return;
            }
            //往抢购订单表写入数据
            PanicBuyingOrders panicBuyingOrders = new PanicBuyingOrders();
            panicBuyingOrders.setUser_id(orders.getOrder_user_id());
            panicBuyingOrders.setGoods_id(orders.getGoods_id());
            panicBuyingOrders.setOrder_id(orders.getOrder_id());
            panicBuyingOrdersDAO.addPB_order(panicBuyingOrders);
            //往 UserInfo中更新数据
            UserInfo byUser_id = userInfoService.findByUser_id(orders.getOrder_user_id());
            int panic_buying_price = panicBuyingGoods.getPanic_buying_price();
            byUser_id.setBeans_spend_day(byUser_id.getBeans_spend_day() + panic_buying_price);//更新该用户今天消费的鲜豆数
            byUser_id.setBeans_spend_total(byUser_id.getBeans_spend_total() + panic_buying_price);//更新该用户消费的总鲜豆数
            byUser_id.setBeans(byUser_id.getBeans() - panic_buying_price);//扣除后更新用户拥有的鲜豆
            userInfoService.updateUserInfo(byUser_id);
            //往 BeansAction中更新数据
            BeansAction beansAction = new BeansAction();
            Goods byGoods_id = goodsService.findByGoods_id(orders.getGoods_id());
            beansAction.setBeans_action_describe("兑换" + byGoods_id.getGoods_name());
            beansAction.setBeans_action_number(- panic_buying_price);
            beansAction.setBeans_action_type(MessageConstant.BEANS_EXPEND);
            beansAction.setBeans_action_time(new Timestamp(new Date().getTime()));
            beansAction.setBeans_action_user_id(orders.getOrder_user_id());
            beansActionService.addBeansAction(beansAction);
            // 向省平台发送请求更新用户鲜豆
            HttpRequestUtils.ProvinceSystemBeanAction(orders.getOrder_user_id(),- panic_buying_price);
            redisService.setCacheObject("panic_buying_goods_order:" + orders.getOrder_user_id() + ":" + orders.getGoods_id(),panicBuyingOrders);
        } else if (orders.getCoupons_id() > 0) { /* 优惠券 */
            //拿到抢购优惠券对象
            PanicBuyingCoupons panicBuyingCoupons = panicBuyingCouponsService.findByCoupons_id(orders.getCoupons_id());
            List<CouponsStock> unsoldItems = couponsStockService.findUnsoldItems(orders.getCoupons_id(), false);
            if (panicBuyingCoupons.getPanic_buying_coupons_stock() >= 1 && unsoldItems.size() > 0){ //解决库存超卖
                panicBuyingCoupons.setPanic_buying_coupons_stock(panicBuyingCoupons.getPanic_buying_coupons_stock() - 1);
                int i = (int)panicBuyingCouponsService.updatePanicBuyingCoupons(panicBuyingCoupons).getObject();
                if (i == 0){  //用户执行减库存的操作失败了，但是依然会去执行下订单的操作，这样就产生了生成的订单数大于卖出的商品数的问题
                    return; //解决办法：判断 update语句是否执行成功，如果未执行成功，直接返回
                    // 注意：mybatis的update语句默认返回匹配的行数，而不是影响的行数，故在jdbc的URL上加 &useAffectedRows=true
                }
                //往订单表写入数据
                orders.setOrder_status(MessageConstant.ORDER_FINISHED);//更新订单状态
                orders.setOrder_time(new Timestamp(new Date().getTime())); //添加下单时间
                ordersService.OrderInsert(orders);
                //往 CouponsStock中更新数据
                CouponsStock couponsStock = unsoldItems.get(0);
                couponsStock.setHave_been_sold(true);
                couponsStock.setSold_order_id(orders.getOrder_id());
                couponsStock.setSold_time(new Timestamp(new Date().getTime()));
                couponsStockService.updateCouponsStock(couponsStock);
                // 往 Exchange中更新数据
                Exchange exchange = new Exchange();
                exchange.setExchange_status(MessageConstant.EXCHANGE_STATUS_EXCHANGED_BUT_NOT_USED);
                exchange.setOrder_id(orders.getOrder_id());
                exchange.setExchange_user_id(orders.getOrder_user_id());
                exchange.setCoupons_item_id(couponsStock.getItem_id());
                exchange.setUse_time(new Timestamp(new Date().getTime()));
                exchangeService.addExchange(exchange);
            }else {
                //如果没有库存 在 Redis中进行标记（有key即可）
                redisService.setCacheObject("isPBCouponsStockEmpty" + orders.getCoupons_id(),0);
                return;
            }
            //往抢购订单表写入数据
            PanicBuyingOrders panicBuyingOrders = new PanicBuyingOrders();
            panicBuyingOrders.setUser_id(orders.getOrder_user_id());
            panicBuyingOrders.setCoupons_id(orders.getCoupons_id());
            panicBuyingOrders.setOrder_id(orders.getOrder_id());
            panicBuyingOrdersDAO.addPB_order(panicBuyingOrders);
            //往 UserInfo中更新数据
            UserInfo byUser_id = userInfoService.findByUser_id(orders.getOrder_user_id());
            int panic_buying_price = panicBuyingCoupons.getPanic_buying_price();
            byUser_id.setBeans_spend_day(byUser_id.getBeans_spend_day() + panic_buying_price);//更新该用户今天消费的鲜豆数
            byUser_id.setBeans_spend_total(byUser_id.getBeans_spend_total() + panic_buying_price);//更新该用户消费的总鲜豆数
            byUser_id.setBeans(byUser_id.getBeans() - panic_buying_price);//扣除后更新用户拥有的鲜豆
            userInfoService.updateUserInfo(byUser_id);
            //往 BeansAction中更新数据
            BeansAction beansAction = new BeansAction();
            Coupons coupons = couponsService.findByCoupon_id(orders.getCoupons_id());
            beansAction.setBeans_action_describe("兑换" + coupons.getCoupon_name());
            beansAction.setBeans_action_number(- panic_buying_price);
            beansAction.setBeans_action_type(MessageConstant.BEANS_EXPEND);
            beansAction.setBeans_action_time(new Timestamp(new Date().getTime()));
            beansAction.setBeans_action_user_id(orders.getOrder_user_id());
            beansActionService.addBeansAction(beansAction);
            // 向省平台发送请求更新用户鲜豆
            HttpRequestUtils.ProvinceSystemBeanAction(orders.getOrder_user_id(),- panic_buying_price);
            redisService.setCacheObject("panic_buying_coupons_order:" + orders.getOrder_user_id() + ":" + orders.getCoupons_id(),panicBuyingOrders);
        }
    }

    @Override
    public PanicBuyingOrders findOrderIdByCondition(long user_id, int type, long thingsId) {
        PanicBuyingOrders panicBuyingOrders = null;
        if (type == 1){
            panicBuyingOrders = panicBuyingOrdersDAO.findPanicBuyingGoodsOrder(user_id,thingsId);
        } else if (type == 2) {
            panicBuyingOrders = panicBuyingOrdersDAO.findPanicBuyingCouponsOrder(user_id,thingsId);
        }
        return panicBuyingOrders;
    }


}
